import * as React from 'react';
import * as _ from 'lodash';
import { Button } from 'antd-mobile-v2';
import { PlusOutlined } from '@ant-design/icons';
import { Props, State } from '../type';
import DetailItem from './detail-item';
import ConditionHandlers, {
  defaultHandler
} from '../../common/form-item/visibilityController';
import { ICondition } from '../../../types';
import { PermissionFields } from '@/plugins/form/types';
import PCComponents from '@/plugins/form/form-components';
import styles from './index.module.less';
import { CurrencyArray } from '../../common/CommonProps';

export class Detail extends React.Component<Props, State> {
  public preValue?: State;

  public static defaultProps = new Props();
  public state = new State();

  constructor(props: Props) {
    super(props);
    this.preValue = undefined;
    const id = 'detail' + new Date().getTime();
    this.state = {
      ids: [id],
      values: [{ id: id }]
    };
    this.onChange = this.onChange.bind(this);
    this.onAdd = this.onAdd.bind(this);
    this.onDelete = this.onDelete.bind(this);
  }

  public componentDidMount() {
    if (this.props.form) {
      this.handleUpdateValues();
    } else {
      this.handleUpdateValuesDetail();
    }
  }

  public getCurrentUnit = (unit: string) => {
    if (!unit) return;
    const currency = CurrencyArray.find((ele) => ele.value === unit)
      ?.currencyType;
    return currency ? currency : unit;
  };

  public componentDidUpdate(prevProps: any) {
    const currentValue = this.props.form?.getFieldValue(this.props.code);
    if (
      !_.isEqual(
        prevProps.formValues?.[this.props.code],
        this.props.formValues?.[this.props.code]
      ) ||
      !_.isEqual(this.preValue, currentValue)
    ) {
      this.preValue = currentValue;
      if (this.props.form) {
        if (
          !_.isEqual(
            JSON.stringify(this.state.values),
            JSON.stringify(
              this.props.form?.getFieldValue(this.props.code) || [{}]
            )
          ) &&
          _.isArray(this.props.form?.getFieldValue(this.props.code))
        ) {
          this.handleUpdateValues();
        }
      } else {
        this.handleUpdateValuesDetail();
      }
    }
  }

  handleUpdateValues = () => {
    const values = this.props.form?.getFieldValue(this.props.code);
    if (!_.isArray(values)) return;
    // 给每一项设置唯一的ID
    values.forEach((item, index) => {
      const id = 'detail' + index + new Date().getTime();
      if (!item.id) {
        item.id = id;
      }
    });
    const ids = values.map((item) => item.id);
    this.setState({
      values,
      ids
    });
  };

  handleUpdateValuesDetail = () => {
    const values = this.props.formValues?.[this.props.code] || [{}];
    if (!_.isArray(values)) return;
    values.forEach((item) => {
      const id = 'detail' + new Date().getTime();
      if (!item.id) {
        item.id = id;
      }
    });
    const ids = values.map((item) => item.id);
    this.setState({
      values,
      ids
    });
  };

  validate = async (_rule: any, _val2: any, callback: any) => {
    const ids = [...this.state.ids];
    let flag = true;
    for (let i = 0; i < ids.length; i++) {
      const name = 'formRef' + ids[i];
      const formItem = this[name]?.props.form;
      if (!formItem) {
        callback();
        return;
      }
      await formItem
        ?.validateFields(() => {
          //
        })
        .catch((err: any) => {
          flag = false;
          if (err) {
            callback(new Error('必填项'));
          }
        });
    }
    if (!flag) {
      callback(new Error('必填项'));
    } else {
      callback();
    }
  };

  onChange(index: number, changed: any, all: any) {
    if (
      Object.keys(changed).length &&
      Object.keys(all).length &&
      this.props.renderMode !== 'detail' &&
      Object.values(all).some((item) => item !== undefined)
    ) {
      // 值的设置和反写
      // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
      // @ts-ignore
      const values = [...this.state.values];
      values[index] = { ...values[index], ...all };
      this.props.form?.setFieldsValue({ [this.props.code]: values });
      // this.props.onContentChange &&
      //   this.props.onContentChange({ values: values, type: 'val' });
    }
  }

  onAdd() {
    const ids = [...this.state.ids];
    const values = [...this.state.values];
    const id = 'detail' + new Date().getTime();
    ids.push(id);
    values.push({ id: id });
    this.setState({ ids, values });
    // this.props.onContentChange &&
    //   this.props.onContentChange({ values: values, type: 'add' });
  }

  onDelete(index: number) {
    const ids = [...this.state.ids];
    const values = [...this.state.values];
    ids.splice(index, 1);
    values.splice(index, 1);
    this.setState({ ids, values });
    this.props.form?.setFieldsValue({ [this.props.code]: values });
    // this.props.onContentChange &&
    //   this.props.onContentChange({ values: values, type: 'del' });
  }

  private handlePermission(renderMode?: FormRenderModes, permission?: PermissionFields) {
    // 详情模式模式
    if (renderMode === 'detail') {
      if (!permission) {
        return 'detail';
      }
      if (permission === 'readonly') {
        return 'detail';
      }
    } else {
      // 发起模式
      if (!permission) {
        return 'editable';
      }
    }
    return permission;
  }

  public render() {
    const {
      name,
      layout,
      renderMode,
      hideAddBtn,
      childTemplate,
      code,
      actionName,
      form,
      visibleConditions,
      children
    } = this.props;

    let allDisabled = false;
    if (!_.isArray(this.state.values)) {
      allDisabled = false;
    } else {
      allDisabled = this.state.values.every(
        (item: { disabled: any }) => item.disabled
      );
    }

    let show = true;
    let hideBtnFlag = false;
    let isHideAdd = false;
    const permissions = React.Children.toArray(children).map((item: any) => {
      return this.handlePermission(renderMode, item.props?.permission);
    });
    let permission;

    if (permissions.every((item: string) => item === 'hide')) {
      permission = 'hide';
    } else if (permissions.every((item: string) => item !== 'editable')) {
      hideBtnFlag = true;
    } else if (permissions.some((item: string) => item === 'editable')) {
      hideBtnFlag = false;
    }
    if (hideAddBtn) {
      isHideAdd = true;
    } else if (!hideAddBtn && hideBtnFlag) {
      isHideAdd = true;
    } else {
      isHideAdd = false;
    }

    if (visibleConditions && visibleConditions.length > 0) {
      show = visibleConditions.every((el: ICondition) => {
        // 不同类型的条件处理器 只有一个条件先按且来写
        let handler = ConditionHandlers[el.componentType];
        if (!handler) {
          handler = defaultHandler;
        }
        let relateBoxValue;
        if (
          !form ||
          !form.getFieldsValue() ||
          Object.keys(form.getFieldsValue()).indexOf(el.conditionName) === -1
        ) {
          relateBoxValue = this.props.formValues?.[el.conditionName];
        } else {
          relateBoxValue = form.getFieldValue(el.conditionName);
        }
        // 解决外面不传form的问题
        return handler(el, relateBoxValue);
      });
    }
    if (!show) {
      return null;
    }
    if (!childTemplate) {
      return null;
    }
    // 权限判断
    if (permission === 'hide') {
      return null;
    }

    return (
      <div
        {...this.props.form?.getFieldProps(code, {
          trigger: this.onChange,
          rules: [{ validator: this.validate }]
        })}
      >
        <div
          style={{
            display: 'flex',
            paddingTop: renderMode === 'detail' ? '4px' : 0
          }}
        >
          <div
            className={
              styles.rightContent + ' ' + (isHideAdd ? styles.noAdd : '')
            }
          >
            <div className={styles.cardWrap}>
              {this.state.ids?.map((el: string, index: React.ReactText) => {
                return (
                  <DetailItem
                    key={el}
                    index={index}
                    len={this.state.ids.length}
                    title={name}
                    layout={layout}
                    allDisabled={allDisabled}
                    permissions={permissions}
                    wrappedComponentRef={(inst: any) =>
                      (this['formRef' + el] = inst)
                    }
                    renderMode={renderMode}
                    hasForm={form}
                    componentClasses={PCComponents}
                    childTemplate={childTemplate}
                    value={this.state.values[index]}
                    onDelete={this.onDelete}
                    onChange={this.onChange}
                  />
                );
              })}
            </div>
            {renderMode === 'detail' ||
              isHideAdd ||
              renderMode === 'actionEditable' ? null : (
                <Button
                  className={styles.detailAddBtn}
                  icon={<PlusOutlined />}
                  onClick={this.onAdd}
                >
                  {actionName || '增加明细'}
                </Button>
              )}
          </div>
        </div>
      </div>
    );
  }
}
